<?php

class Soul_Template_Html_Form_Select_Tree extends Soul_Template_Html_Form_Select {

    private $_treeData = NULL;
    private $_dataSource = NULL;
    
    public function __construct() {
        $this->templateName = 'form/treeselect';
        parent::__construct();
    }

    public function getTreeData() {
        return $this->_treeData;
    }
    
    public function setOption($label, $value, $disabled = FALSE, $attributes = array(), $group = NULL) {
        $option = array(
            'label' => $label,
            'value' => $value,
            'disabled' => $disabled,
            'attributes' => $attributes
        );
        $this->options[] = $option;
        return $this;
    }

    public function bindData($datas, $startValue = NULL, $itemKeys = NULL) {
        $this->_dataSource = $datas;
        $this->_treeData = $this->buildTreeData($startValue, $itemKeys, 0);
        return $this;
    }    

    private function buildTreeData($parentValue, $itemKeys, $level) {
        $result = array();
        for ($i = 0; $i < count($this->_dataSource); $i++) {
            $item = $this->_dataSource[$i];
            if ($item[$itemKeys['parentKey']] == $parentValue) {
                $children = $this->buildTreeData($item[$itemKeys['childKey']], $itemKeys, $level + 1);
                $label = $this->getFormatLabel($item[$itemKeys['labelKey']]);
                $value = $this->getFormatValue($item[$itemKeys['valueKey']]);
                $treeItem = array(
                    'value' => $value,
                    'label' => str_pad($label, $level + strlen($label), '-', STR_PAD_LEFT),
                    'disabled' => isset($itemKeys['disabledKey']) ? $item[$itemKeys['disabledKey']] : FALSE
                );
                if (count($children) > 0) {
                    $treeItem['children'] = $children;
                }
                $result[] = $treeItem;
            }
        }
        return $result;
    }

    protected function renderEditable() {
        if (!$this->getEnabled()) {
            $this->addClass('disabled');
        }

        $this->setAttribute('id', $this->getId())
                ->setAttribute('name', $this->getName());
        if ($this->getSize() > 1) {
            $this->setAttribute('size', $this->getSize());
        }
        if (!$this->getEnabled()) {
            $this->setAttribute('disabled', 'disabled');
        }
        if ($this->getMultiple()) {
            $this->setAttribute('multiple', 'multiple');
        }

        $selectedValues = is_array($this->getValue()) ? $this->getValue() : array($this->getValue());
        $result = '<select ' . $this->getAttributeHtml() . '>';
        if(count($this->options) > 0){
            foreach($this->options as $option){
                $result .= '<option value="' 
                        . $this->getFormatValue($option['value'])
                        . '">' . $this->getFormatLabel($option['label'])
                        . '</option>';
            }
        }
        $result .= $this->createOptionHtml($this->_treeData, $selectedValues);
        return $result . '</select>';
    }

    private function createOptionHtml($datas, $selectedValues) {
        $result = '';
        foreach ($datas as $data) {
            $selected = '';
            if (!empty($selectedValues)) {
                foreach ($selectedValues as $sv) {
                    if (strlen($sv) == strlen($data['value']) && $sv == $data['value']) {
                        $selected = ' selected="selected"';
                    }
                }
            }
            $result .= '<option value="' 
                    . $data['value']
                    . '"' . $selected . '>'
                    . $data['label']
                    . '</option>';
            if (array_key_exists('children', $data)) {
                $result .= $this->createOptionHtml($data['children'], $selectedValues);
            }
        }
        return $result;
    }

}